﻿using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;
//using System.Text.Json.Serialization;

namespace NewRetail.Application.Components.WeChat.QrCode.Model
{
    #region 二维码类型的枚举
    /// <summary>
    /// 二维码类型的枚举
    /// </summary>
    public enum ActionNameType
    {
        [Description("临时的整型参数值")]
        QR_SCENE,
        [Description("临时的字符串参数值")]
        QR_STR_SCENE,
        [Description("永久的整型参数值")]
        QR_LIMIT_SCENE,
        [Description("永久的字符串参数值")]
        QR_LIMIT_STR_SCENE
    }
    #endregion

    #region QrCode模型
    /// <summary>
    /// 二维码类型。
    /// </summary>
    public enum QrCodeType
    {
        /// <summary>
        /// 临时。
        /// </summary>
        Temporary = 0,
        /// <summary>
        /// 临时的字符串参数值。
        /// </summary>
        TemporaryString = 1,

        /// <summary>
        /// 永久。
        /// </summary>
        Forever = 2,

        /// <summary>
        /// 永久的字符串参数值。
        /// </summary>
        ForeverString = 3
    }

    /// <summary>
    /// 创建二维码模型基类。
    /// </summary>
    public class CreateQrCodeModel
    {
        #region Field

        /// <summary>
        /// 二维码类型映射。
        /// </summary>
        public static readonly IDictionary<QrCodeType, string> QrCodeTypeMappings = new Dictionary<QrCodeType, string>
        {
            {QrCodeType.Temporary, "QR_SCENE"},
            {QrCodeType.TemporaryString, "QR_STR_SCENE"},
            {QrCodeType.Forever, "QR_LIMIT_SCENE"},
            {QrCodeType.ForeverString, "QR_LIMIT_STR_SCENE"}
        };

        #endregion Field

        #region Constructor

        /// <summary>
        /// 初始化一个新的创建二维码模型。
        /// </summary>
        protected CreateQrCodeModel()
        {
        }

        /// <summary>
        /// 初始化一个新的创建二维码模型。
        /// </summary>
        /// <param name="qrCodeType">二维码类型。</param>
        protected CreateQrCodeModel(QrCodeType qrCodeType)
        {
            Type = qrCodeType;
        }

        #endregion Constructor

        /// <summary>
        /// 二维码类型。
        /// </summary>
        [JsonIgnore]
        public QrCodeType Type
        {
            get
            {
                var item = QrCodeTypeMappings.SingleOrDefault(i => i.Value.Equals(ActionName));
                if (item.Value == null)
                    throw new NotSupportedException("不支持的二维码类型：" + ActionName);
                return item.Key;
            }
            set
            {
                ActionName = QrCodeTypeMappings[value];
            }
        }

        /// <summary>
        /// 二维码类型，QR_SCENE为临时,QR_STR_SCENE为临时的字符串参数值,QR_LIMIT_SCENE为永久,QR_LIMIT_STR_SCENE为永久的字符串参数值
        /// </summary>
        [JsonProperty("action_name")]
        internal string ActionName { get; set; }

        internal sealed class QrCodeInfo
        {
            public sealed class SceneIdInfo
            {
                [JsonProperty("scene_id")]
                public uint SceneId { get; set; }
            }

            public sealed class SceneStringInfo
            {
                [JsonProperty("scene_str")]
                public string SceneString { get; set; }
            }

            [JsonProperty("scene")]
            public object Scene { get; set; }
        }

        /// <summary>
        /// 二维码详细信息。
        /// </summary>
        [JsonProperty("action_info")]
        internal QrCodeInfo ActionInfo { get; set; }

        /// <summary>
        /// 场景值ID，临时二维码时为32位非0整型，永久二维码时最大值为100000（目前参数只支持1--100000）
        /// </summary>
        [JsonIgnore]
        public virtual uint SceneId
        {
            get
            {
                return ((QrCodeInfo.SceneIdInfo)ActionInfo.Scene).SceneId;
            }
            /*            set
                        {
                            if (value <= 0 || value > 100000)
                                throw new ArgumentException("SceneId 必需在 1~100000 之间。");

                            if (this is CreateForeverQrCodeModel)
                            {
                                Type = QrCodeType.Forever;
                            }

                            ((QrCodeInfo.SceneIdInfo)ActionInfo.Scene).SceneId = value;
                        }*/
        }

        /// <summary>
        /// 场景值ID(字符串)，字符串类型，长度限制为1到64
        /// </summary>
        [JsonIgnore]
        public virtual string SceneString
        {
            get
            {
                return ((QrCodeInfo.SceneStringInfo)ActionInfo.Scene).SceneString;
            }
        }
    }

    /// <summary>
    /// 创建临时二维码模型。
    /// </summary>
    public class CreateTemporaryQrCodeModel : CreateQrCodeModel
    {
        /// <summary>
        /// 初始化一个新的创建临时二维码模型。
        /// </summary>
        /// <param name="sceneId">数字型的场景Id。</param>
        /// <param name="expireSeconds">该二维码有效时间，以秒为单位。 最大不超过604800（即7天）。</param>
        public CreateTemporaryQrCodeModel(uint sceneId, uint expireSeconds = 604800)
            : base(QrCodeType.Temporary)
        {
            ActionInfo = new QrCodeInfo
            {
                Scene = new QrCodeInfo.SceneIdInfo { SceneId = sceneId }
            };
            Type = QrCodeType.Temporary;
            ExpireSeconds = expireSeconds;
        }

        /// <summary>
        /// 初始化一个新的创建临时二维码模型。
        /// </summary>
        /// <param name="sceneString">字符串型的场景Id。</param>
        /// <param name="expireSeconds">该二维码有效时间，以秒为单位。 最大不超过604800（即7天）。</param>
        public CreateTemporaryQrCodeModel(string sceneString, uint expireSeconds = 604800)
            : base(QrCodeType.TemporaryString)
        {
            ActionInfo = new QrCodeInfo
            {
                Scene = new QrCodeInfo.SceneStringInfo { SceneString = sceneString }
            };
            Type = QrCodeType.TemporaryString;
            ExpireSeconds = expireSeconds;
        }

        private uint _expireSeconds;

        /// <summary>
        /// 该二维码有效时间，以秒为单位。 最大不超过2592000（即30天）。
        /// </summary>
        [JsonProperty("expire_seconds"), Range(0, 2592000)]
        public uint ExpireSeconds
        {
            get { return _expireSeconds; }
            set
            {
                if (value < 0 || value > 2592000)
                    throw new ArgumentOutOfRangeException("value", value, "有效时间不能小于0秒且不大于2592000秒。");
                _expireSeconds = value;
            }
        }

        /// <summary>
        /// 场景值ID（字符串形式的ID）
        /// </summary>
        [JsonIgnore]
        public override string SceneString
        {
            get { return ((QrCodeInfo.SceneStringInfo)ActionInfo.Scene).SceneString; }
        }
    }

    /// <summary>
    /// 创建永久二维码模型。
    /// </summary>
    public class CreateForeverQrCodeModel : CreateQrCodeModel
    {
        /// <summary>
        /// 初始化一个新的创建永久二维码模型。
        /// </summary>
        /// <param name="sceneId">数字型的场景Id。</param>
        public CreateForeverQrCodeModel(uint sceneId)
            : base(QrCodeType.Forever)
        {
            ActionInfo = new QrCodeInfo
            {
                Scene = new QrCodeInfo.SceneIdInfo { SceneId = sceneId }
            };
        }

        /// <summary>
        /// 初始化一个新的创建永久二维码模型。
        /// </summary>
        /// <param name="sceneString">字符串型的场景Id。</param>
        public CreateForeverQrCodeModel(string sceneString)
            : base(QrCodeType.ForeverString)
        {
            ActionInfo = new QrCodeInfo
            {
                Scene = new QrCodeInfo.SceneStringInfo { SceneString = sceneString }
            };
        }

        /// <summary>
        /// 场景值ID（字符串形式的ID），字符串类型，长度限制为1到64，仅永久二维码支持此字段。
        /// </summary>
        [JsonIgnore]
        public override string SceneString
        {
            get { return ((QrCodeInfo.SceneStringInfo)ActionInfo.Scene).SceneString; }
            /*            set
                        {
                            Type = QrCodeType.ForeverString;
                            ((QrCodeInfo.SceneStringInfo)ActionInfo.Scene).SceneString = value;
                        }*/
        }
    }

    /// <summary>
    /// 创建二维码结果模型。
    /// </summary>
    public class CreateQrCodeResultModel
    {
        /// <summary>
        /// 获取的二维码ticket，凭借此ticket可以在有效时间内换取二维码。
        /// </summary>
        [JsonProperty("Ticket")]
        [System.Text.Json.Serialization.JsonPropertyName("ticket")]
        public string Ticket { get; set; }

        /// <summary>
        /// 该二维码有效时间，以秒为单位。 最大不超过604800（即7天）。
        /// </summary>
        [JsonProperty("expire_seconds"), Range(0, 604800)]
        [System.Text.Json.Serialization.JsonPropertyName("expiresIn")]
        public int ExpiresIn { get; set; }

        /// <summary>
        /// 二维码图片解析后的地址，开发者可根据该地址自行生成需要的二维码图片.
        /// </summary>
        [System.Text.Json.Serialization.JsonPropertyName("url")]
        public string Url { get; set; }
    }

    /// <summary>
    /// 获取二维码结果模型。
    /// </summary>
    public class GetQrCodeResultModel
    {
        /// <summary>
        /// 内容长度。
        /// </summary>
        public long ContentLength { get; set; }

        /// <summary>
        /// 内容类型。
        /// </summary>
        public string ContentType { get; set; }

        /// <summary>
        /// 二维码数据。
        /// </summary>
        public byte[] Data { get; set; }
    }

    /// <summary>
    /// 创建二维码返回结果
    /// </summary>
    public  class WarehouseQrCodeResult
    {
        /// <summary>
        /// url地址
        /// </summary>
        public List<string> WarehouseQrCodeUrls { get; set; }

    }

    #endregion
}
